home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / quicktime / timecodes / qttimecode / application files / comapplication.c next >
Encoding:
Text File  |  2000-06-23  |  12.3 KB  |  482 lines

  1. //////////
  2. //
  3. //    File:        ComApplication.c
  4. //
  5. //    Contains:    Application-specific code for basic QuickTime movie display and control.
  6. //                This file is used for BOTH MacOS and Windows.
  7. //
  8. //    Written by:    Tim Monroe
  9. //                Based (heavily!) on the MovieShell code written by Apple DTS.
  10. //
  11. //    Copyright:    © 1994-1998 by Apple Computer, Inc., all rights reserved.
  12. //
  13. //    Change History (most recent first):
  14. //
  15. //       <12>         12/16/98    rtm        removed all QTVR API calls, so we can remove QTVR.lib from project
  16. //       <11>         05/18/98    rtm        begun QTTimeCode sample
  17. //       <10>         10/23/97    rtm        moved InitializeQTVR to InitApplication, TerminateQTVR to StopApplication
  18. //       <9>         10/13/97    rtm        reworked HandleApplicationMenu to use menu identifiers
  19. //       <8>         09/11/97    rtm        merged MacApplication.c and WinApplication.c into ComApplication.c
  20. //       <7>         08/21/97    rtm        first file for Windows; based on MacApplication.c for Mac sample code
  21. //       <6>         06/04/97    rtm        removed call to QTVRUtils_IsQTVRMovie in InitApplicationWindowObject
  22. //       <5>         02/06/97    rtm        fixed window resizing code
  23. //       <4>         12/05/96    rtm        added hooks into MacFramework.c: StopApplication, InitApplicationWindowObject
  24. //       <3>         12/02/96    rtm        added cursor updating to DoIdle
  25. //       <2>         11/27/96    rtm        conversion to personal coding style; added preliminary QTVR support
  26. //       <1>         12/21/94    khs        first file
  27. //       
  28. //
  29. //    QTShell is a simple QuickTime viewer framework. It demonstrates how to incorporate 
  30. //    QuickTime and QuickTime VR movies into an application. QTShell is based heavily on the 
  31. //    MovieShell QuickTime playback framework included with the DTS QT sample code.
  32. //
  33. //////////
  34.  
  35. // header files
  36. #include "ComApplication.h"
  37. #include "QTTimeCode.h"
  38.   
  39. // global variables for Macintosh code
  40. #if TARGET_OS_MAC
  41. #endif
  42.  
  43. // global variables for Windows code
  44. #if TARGET_OS_WIN32
  45. extern HWND                ghWnd;                                    // the MDI frame window; this window has the menu bar
  46. extern int                gNumWindowsOpen;
  47. extern LPSTR            gCmdLine;
  48. #endif
  49.  
  50. long                    gMaxMilliSecToUse = 0L;
  51.  
  52.  
  53. //////////
  54. //
  55. // InitApplication
  56. // Do any application-specific initialization.
  57. //
  58. // The theStartPhase parameter determines which "phase" of application start-up is executed,
  59. // *before* the MDI frame window is created or *after*. This distinction is relevant only on
  60. // Windows, so on MacOS, you should always use kInitAppPhase_BothPhases.
  61. //
  62. //////////
  63.  
  64. void InitApplication (UInt32 theStartPhase)
  65. {
  66.     // ***do any start-up activities that should occur before the MDI frame window is created
  67.     if (theStartPhase & kInitAppPhase_BeforeCreateFrameWindow) {
  68.  
  69.     }    // end of kInitAppPhase_BeforeCreateFrameWindow
  70.  
  71.     // ***do any start-up activities that should occur after the MDI frame window is created
  72.     if (theStartPhase & kInitAppPhase_AfterCreateFrameWindow) {
  73. #if TARGET_OS_WIN32
  74.         // on Windows, open as movie documents any files specified on the command line
  75.         SendMessage(ghWnd, WM_OPENDROPPEDFILES, 0L, 0L);
  76. #endif
  77.     }    // end of kInitAppPhase_AfterCreateFrameWindow
  78. }
  79.  
  80.  
  81. //////////
  82. //
  83. // StopApplication
  84. // Do any application-specific shut-down.
  85. //
  86. // The theStopPhase parameter determines which "phase" of application shut-down is executed,
  87. // *before* any open movie windows are destroyed or *after*.
  88. //
  89. //////////
  90.  
  91. void StopApplication (UInt32 theStopPhase)
  92. {
  93.     // @@@INSERT APPLICATION-SPECIFIC SHUT-DOWN FUNCTIONALITY HERE
  94.     
  95.     // do any shut-down activities that should occur after the movie windows are destroyed
  96.     if (theStopPhase & kStopAppPhase_AfterDestroyWindows) {
  97.                     
  98.     }    // end of kStopAppPhase_AfterDestroyWindows
  99. }
  100.  
  101.  
  102. //////////
  103. //
  104. // DoIdle
  105. // Do any processing that can/should occur at idle time.
  106. //
  107. //////////
  108.  
  109. void DoIdle (WindowReference theWindow)
  110. {
  111.     WindowObject         myWindowObject = NULL;
  112.     GrafPtr             mySavedPort;
  113.     
  114.     GetPort(&mySavedPort);
  115.     MacSetPort(GetPortFromWindowReference(theWindow));
  116.     
  117.     myWindowObject = GetWindowObjectFromWindow(theWindow);
  118.     if (myWindowObject != NULL) {
  119.         MovieController        myMC = NULL;
  120.     
  121.         myMC = (**myWindowObject).fController;
  122.         if (myMC != NULL) {
  123.  
  124. #if TARGET_OS_MAC
  125.             // restore the cursor to the arrow
  126.             // if it's outside the front movie window or outside the window's visible region
  127.             if (theWindow == GetFrontMovieWindow()) {
  128.                 Rect    myRect;
  129.                 Point    myPoint;
  130.                 
  131.                 GetMouse(&myPoint);
  132.                 MCGetControllerBoundsRect(myMC, &myRect);
  133.                 if (!MacPtInRect(myPoint, &myRect) || !PtInRgn(myPoint, GetPortFromWindowReference(theWindow)->visRgn))
  134.                     MacSetCursor(&qd.arrow);
  135.             }
  136. #endif    // TARGET_OS_MAC
  137.         }
  138.     }
  139.     
  140.     // @@@INSERT APPLICATION-SPECIFIC IDLE-TIME FUNCTIONALITY HERE
  141.     
  142.     MacSetPort(mySavedPort);
  143. }
  144.  
  145.  
  146. //////////
  147. //
  148. // DoUpdateWindow
  149. // Update the specified window.
  150. //
  151. //////////
  152.  
  153. void DoUpdateWindow (WindowReference theWindow, Rect *theRefreshArea)
  154. {
  155.     GrafPtr             mySavedPort;
  156.     
  157.     GetPort(&mySavedPort);
  158.     MacSetPort(GetPortFromWindowReference(theWindow));
  159.     
  160.     BeginUpdate(GetPortFromWindowReference(theWindow));
  161.     //EraseRect(theRefreshArea);        // this is important, for non-rectangular movies
  162.     
  163.     // @@@INSERT APPLICATION-SPECIFIC DRAWING FUNCTIONALITY HERE
  164.     
  165.     // draw the movie controller and its movie
  166.     MCDoAction(GetMCFromWindow(theWindow), mcActionDraw, theWindow);
  167.     
  168.     EndUpdate(GetPortFromWindowReference(theWindow));
  169.     MacSetPort(mySavedPort);
  170. }
  171.  
  172.  
  173. //////////
  174. //
  175. // HandleContentClick
  176. // Handle mouse button clicks in the specified window.
  177. //
  178. //////////
  179.  
  180. void HandleContentClick (WindowReference theWindow, EventRecord *theEvent)
  181. {
  182. #pragma unused(theEvent)
  183.  
  184.     GrafPtr             mySavedPort;
  185.     
  186.     GetPort(&mySavedPort);
  187.     MacSetPort(GetPortFromWindowReference(theWindow));
  188.     
  189.     // @@@INSERT APPLICATION-SPECIFIC CONTENT CLICKING FUNCTIONALITY HERE
  190.  
  191.     MacSetPort(mySavedPort);
  192. }
  193.  
  194.  
  195. //////////
  196. //
  197. // HandleApplicationKeyPress
  198. // Handle application-specific key presses.
  199. // Returns true if the key press was handled, false otherwise.
  200. //
  201. //////////
  202.  
  203. Boolean HandleApplicationKeyPress (char theCharCode)
  204. {
  205.     Boolean        isHandled = true;
  206.     
  207.     switch (theCharCode) {
  208.     
  209.         // @@@HANDLE APPLICATION-SPECIFIC KEY PRESSES HERE
  210.  
  211.         default:
  212.             isHandled = false;
  213.             break;
  214.     }
  215.  
  216.     return(isHandled);
  217. }
  218.  
  219.  
  220. #if TARGET_OS_MAC
  221. //////////
  222. //
  223. // CreateMovieWindow
  224. // Create a window to display a movie in.
  225. //
  226. //////////
  227.  
  228. WindowRef CreateMovieWindow (Rect *theRect, Str255 theTitle)
  229. {
  230.     WindowRef            myWindow;
  231.     
  232.     myWindow = NewCWindow(NULL, theRect, theTitle, false, noGrowDocProc, (WindowPtr)-1L, true, 0);
  233.     return(myWindow);
  234. }
  235. #endif
  236.  
  237.  
  238. //////////
  239. //
  240. // HandleApplicationMenu
  241. // Handle selections in the application's menus.
  242. //
  243. // The theMenuItem parameter is a UInt16 version of the Windows "menu item identifier". 
  244. // When called from Windows, theMenuItem is simply the menu item identifier passed to the window proc.
  245. // When called from MacOS, theMenuItem is constructed like this:
  246. //     *high-order 8 bits == the Macintosh menu ID (1 thru 256)
  247. //     *low-order 8 bits == the Macintosh menu item (sequential from 1 to ordinal of last menu item in menu)
  248. // In this way, we can simplify the menu-handling code. There are, however, some limitations,
  249. // mainly that the menu item identifiers on Windows must be derived from the Mac values. 
  250. //
  251. //////////
  252.  
  253. void HandleApplicationMenu (UInt16 theMenuItem)
  254. {
  255.     WindowObject        myWindowObject = NULL;
  256.     MovieController     myMC = NULL;
  257.     Movie                 myMovie = NULL;
  258.     
  259.     myWindowObject = GetWindowObjectFromFrontWindow();
  260.     if (myWindowObject != NULL) {
  261.         myMC = (**myWindowObject).fController;
  262.         myMovie = (**myWindowObject).fMovie;
  263.     }
  264.     
  265.     // make sure we have a movie and a movie controller
  266.     if ((myMovie == NULL) || (myMC == NULL))
  267.         return;
  268.         
  269.     switch (theMenuItem) {
  270.         case IDM_ADD_TIMECODE:
  271.             if (QTTC_GetTimeCodeOptions()) {
  272.                 
  273.                 // delete any existing timecode tracks
  274.                 QTTC_DeleteTimeCodeTracks(myMovie);
  275.                                 
  276.                 // add a new timecode track
  277.                 QTTC_AddTimeCodeToMovie(myMovie, VideoMediaType);
  278.                 
  279.                 // fix rectangle
  280.                 MCMovieChanged(myMC, myMovie);
  281.                 
  282.                 // mark movie window as dirty
  283.                 (**myWindowObject).fDirty = true;
  284.             }
  285.             break;
  286.  
  287.         case IDM_DELETE_TIMECODE:
  288.             QTTC_DeleteTimeCodeTracks(myMovie);
  289.             
  290.             // fix rectangle
  291.             MCMovieChanged(myMC, myMovie);
  292.                 
  293.             // mark movie window as dirty
  294.             (**myWindowObject).fDirty = true;
  295.             break;
  296.         
  297.         case IDM_GET_TIMECODE:
  298.             QTTC_ShowCurrentTimeCode(myMovie);
  299.             break;
  300.         
  301.         case IDM_GET_TIMECODE_SOURCE:
  302.             QTTC_ShowTimeCodeSource(myMovie);
  303.             break;
  304.         
  305.         case IDM_TOGGLE_TIMECODE_DISPLAY:
  306.             QTTC_ToggleTimeCodeDisplay(myMC);
  307.             break;
  308.         
  309.         default:
  310.             break;
  311.     }    // switch (theMenuItem)
  312. }
  313.  
  314.  
  315. //////////
  316. //
  317. // AdjustApplicationMenus
  318. // Adjust state of items in the application's menus.
  319. //
  320. // Currently, the Mac application has only one app-specific menu ("Test"); you could change that.
  321. //
  322. //////////
  323.  
  324. void AdjustApplicationMenus (WindowReference theWindow, MenuReference theMenu)
  325. {
  326.     WindowObject        myWindowObject = NULL; 
  327.     MovieController     myMC = NULL;
  328.     Movie                 myMovie = NULL;
  329.     MenuReference        myMenu;
  330.     
  331. #if TARGET_OS_WIN32
  332.     myMenu = theMenu;
  333. #elif TARGET_OS_MAC
  334.     myMenu = GetMenuHandle(kTestMenu);
  335. #endif
  336.     
  337.     if (theWindow != NULL)
  338.         myWindowObject = GetWindowObjectFromWindow(theWindow);
  339.  
  340.     if (myWindowObject != NULL) {
  341.         myMC = (**myWindowObject).fController;
  342.         myMovie = (**myWindowObject).fMovie;
  343.     }
  344.     
  345.     // we don't allow creating new files here...
  346. #if TARGET_OS_MAC
  347.     SetMenuItemState(GetMenuHandle(mFile), iNew, kDisableMenuItem);
  348. #endif
  349.  
  350.     // first, assume everything should be disabled
  351.     SetMenuItemState(myMenu, IDM_ADD_TIMECODE, kDisableMenuItem);
  352.     SetMenuItemState(myMenu, IDM_DELETE_TIMECODE, kDisableMenuItem);
  353.     SetMenuItemState(myMenu, IDM_GET_TIMECODE, kDisableMenuItem);
  354.     SetMenuItemState(myMenu, IDM_GET_TIMECODE_SOURCE, kDisableMenuItem);
  355.     SetMenuItemState(myMenu, IDM_TOGGLE_TIMECODE_DISPLAY, kDisableMenuItem);
  356.     
  357.     if ((myMovie != NULL) && !QTTC_MovieHasTimeCodeTrack(myMovie)) {
  358.         SetMenuItemState(myMenu, IDM_ADD_TIMECODE, kEnableMenuItem);
  359.     }
  360.     
  361.     if ((myMovie != NULL) && QTTC_MovieHasTimeCodeTrack(myMovie)) {
  362.         SetMenuItemState(myMenu, IDM_DELETE_TIMECODE, kEnableMenuItem);
  363.         SetMenuItemState(myMenu, IDM_GET_TIMECODE, kEnableMenuItem);
  364.         SetMenuItemState(myMenu, IDM_GET_TIMECODE_SOURCE, kEnableMenuItem);
  365.         SetMenuItemState(myMenu, IDM_TOGGLE_TIMECODE_DISPLAY, kEnableMenuItem);
  366.     }
  367.     
  368. }
  369.  
  370.  
  371. //////////
  372. //
  373. // DoApplicationEventLoopAction
  374. // Perform any application-specific event loop actions.
  375. //
  376. // Return true to indicate that we've completely handled the event here, false otherwise.
  377. //
  378. //////////
  379.  
  380. Boolean DoApplicationEventLoopAction (EventRecord *theEvent)
  381. {
  382. #pragma unused(theEvent)
  383.     
  384.     return(false);            // no-op for now
  385. }
  386.  
  387.  
  388. //////////
  389. //
  390. // AddControllerFunctionality
  391. // Configure the movie controller.
  392. //
  393. //////////
  394.  
  395. void AddControllerFunctionality (MovieController theMC)
  396. {
  397.     long            myControllerFlags;
  398.     
  399.     // CLUT table use
  400.     MCDoAction(theMC, mcActionGetFlags, &myControllerFlags);
  401.     MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags | mcFlagsUseWindowPalette));
  402.  
  403.     // enable keyboard event handling
  404.     MCDoAction(theMC, mcActionSetKeysEnabled, (void *)true);
  405.     
  406.     // disable drag support
  407.     MCDoAction(theMC, mcActionSetDragEnabled, (void *)false);
  408. }
  409.  
  410.  
  411. //////////
  412. //
  413. // InitApplicationWindowObject
  414. // Do any application-specific initialization of the window object.
  415. //
  416. //////////
  417.  
  418. void InitApplicationWindowObject (WindowObject theWindowObject)
  419. {
  420. #pragma unused(theWindowObject)
  421. }
  422.  
  423.  
  424. //////////
  425. //
  426. // RemoveApplicationWindowObject
  427. // Do any application-specific clean-up of the window object.
  428. //
  429. //////////
  430.  
  431. void RemoveApplicationWindowObject (WindowObject theWindowObject)
  432. {
  433. #pragma unused(theWindowObject)
  434.     // @@@INSERT APPLICATION-SPECIFIC WINDOW OBJECT CLEAN-UP HERE
  435.  
  436.     // DoDestroyMovieWindow in MacFramework.c or MovieWndProc in WinFramework.c
  437.     // releases the window object itself
  438. }
  439.  
  440.  
  441. //////////
  442. //
  443. // ApplicationMCActionFilterProc 
  444. // Intercept some mc actions for the movie controller.
  445. //
  446. // NOTE: The theRefCon parameter is a handle to a window object record.
  447. //
  448. //////////
  449.  
  450. PASCAL_RTN Boolean ApplicationMCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon)
  451. {
  452. #pragma unused(theMC)
  453.  
  454.     Boolean                isHandled = false;            // false => allow controller to process the action
  455.     WindowObject        myWindowObject = NULL;
  456.     
  457.     myWindowObject = (WindowObject)theRefCon;
  458.     if (myWindowObject == NULL)
  459.         return(isHandled);
  460.         
  461.     switch (theAction) {
  462.     
  463.         // handle window resizing
  464.         case mcActionControllerSizeChanged:
  465.             SizeWindowToMovie(myWindowObject);
  466.             break;
  467.  
  468.         // handle idle events
  469.         case mcActionIdle:
  470.             DoIdle((**myWindowObject).fWindow);
  471.             break;
  472.             
  473.         default:
  474.             break;
  475.             
  476.     }    // switch (theAction)
  477.     
  478.     return(isHandled);    
  479. }
  480.  
  481.  
  482.